package com.zzw.springboot.controller;

import com.zzw.springboot.util.RedisLockUtil;
import com.zzw.springboot.util.RedissonLockUtil;
import com.zzw.springboot.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * Redis分布式锁演示控制器
 * 用于展示基础Redis锁和Redisson锁的差异
 */
@RestController
@RequestMapping("/redis/lock")
public class RedisLockDemoController {

    @Autowired
    private RedisLockUtil redisLockUtil;

    @Autowired
    private RedissonLockUtil redissonLockUtil;

    /**
     * 测试普通Redis锁 - 不支持自动续期
     * 
     * @param seconds 业务执行时间（秒）
     * @param timeout 锁超时时间（秒）
     * @return 执行结果
     */
    @GetMapping("/basic")
    public Result testBasicLock(
            @RequestParam(defaultValue = "5") int seconds,
            @RequestParam(defaultValue = "30") int timeout) {
        
        String lockKey = "demo:basic:lock";
        String value = UUID.randomUUID().toString();
        Map<String, Object> result = new HashMap<>();
        
        long startTime = System.currentTimeMillis();
        boolean locked = redisLockUtil.tryLock(lockKey, value, timeout);
        result.put("locked", locked);
        result.put("lockType", "Basic Redis Lock (SETNX)");
        result.put("timeout", timeout + "s");
        result.put("businessTime", seconds + "s");
        
        if (locked) {
            try {
                // 模拟业务处理
                Thread.sleep(seconds * 1000L);
                result.put("message", "处理成功");
                
                // 如果业务执行时间超过锁超时时间，锁可能已经过期
                if (seconds > timeout) {
                    result.put("warning", "业务执行时间超过锁超时时间，锁可能已经过期！");
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                result.put("message", "处理被中断");
            } finally {
                // 尝试释放锁
                boolean released = redisLockUtil.releaseLock(lockKey, value);
                result.put("released", released);
                
                // 如果无法释放锁，可能是锁已经过期
                if (!released) {
                    result.put("error", "锁已过期或被其他线程获取，无法释放");
                }
            }
        } else {
            result.put("message", "获取锁失败");
        }
        
        long endTime = System.currentTimeMillis();
        result.put("executionTime", (endTime - startTime) + "ms");
        
        return Result.success(result);
    }
    
    /**
     * 测试Redisson锁 - 支持自动续期
     * 
     * @param seconds 业务执行时间（秒）
     * @param waitTime 等待锁的时间（秒）
     * @return 执行结果
     */
    @GetMapping("/watchdog")
    public Result testWatchdogLock(
            @RequestParam(defaultValue = "5") int seconds,
            @RequestParam(defaultValue = "3") int waitTime) {
        
        String lockKey = "demo:watchdog:lock";
        Map<String, Object> result = new HashMap<>();
        
        long startTime = System.currentTimeMillis();
        try {
            // 尝试获取锁，等待指定时间，使用看门狗机制（不设置超时时间）
            boolean locked = redissonLockUtil.tryLock(lockKey, waitTime, -1, TimeUnit.SECONDS);
            result.put("locked", locked);
            result.put("lockType", "Redisson WatchDog Lock");
            result.put("waitTime", waitTime + "s");
            result.put("businessTime", seconds + "s");
            
            if (locked) {
                try {
                    // 模拟业务处理 - 无论多长时间，看门狗都会自动续期
                    Thread.sleep(seconds * 1000L);
                    result.put("message", "处理成功 - 锁自动续期，保持有效");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    result.put("message", "处理被中断");
                } finally {
                    // 释放锁
                    redissonLockUtil.unlock(lockKey);
                    result.put("released", true);
                }
            } else {
                result.put("message", "获取锁失败 - 等待超时");
            }
        } catch (Exception e) {
            result.put("error", e.getMessage());
            result.put("message", "锁操作异常");
        }
        
        long endTime = System.currentTimeMillis();
        result.put("executionTime", (endTime - startTime) + "ms");
        
        return Result.success(result);
    }
    
    /**
     * 锁测试状态
     */
    @GetMapping("/status")
    public Result getLockStatus(
            @RequestParam(defaultValue = "demo:basic:lock") String basicLockKey,
            @RequestParam(defaultValue = "demo:watchdog:lock") String watchdogLockKey) {
        
        Map<String, Object> result = new HashMap<>();
        
        // 检查基础锁状态
        boolean basicLockExists = false;
        try {
            // 原始RedisLockUtil没有提供检查锁状态的方法
            // 这里可以使用RedisTemplate直接检查，但简化起见，我们只返回Redisson锁的状态
            result.put("basicLockNote", "基础Redis锁不支持直接检查状态");
        } catch (Exception e) {
            result.put("basicLockError", e.getMessage());
        }
        
        // 检查Redisson锁状态
        boolean watchdogLocked = redissonLockUtil.isLocked(watchdogLockKey);
        result.put("watchdogLockExists", watchdogLocked);
        
        return Result.success(result);
    }
} 